package com.kingwood.algorithm.test;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Author 22025812
 * @Description: TODO
 * @Date: 2024/3/1 9:35
 * @Modified By：
 * @Version 1.0
 */
public class LuojiFenxi {

    /**
     * 求幸存数之和
     * https://fcqian.blog.csdn.net/article/details/134883009*
     * 此题用动态数组实现，也可以使用循环链表避免越界问题
     * @param arr
     * @param jump
     * @param left
     * @return
     */
    public static int sumOfLeft(int[] arr, int jump, int left) {
        int ans = 0;
        ArrayList<Integer> list = (ArrayList<Integer>) Arrays.stream(arr).boxed().collect(Collectors.toList());

        int start = 1;
        while (list.size() > left) {
            start += jump;
            // 为避免越界
            start = start % list.size();
            list.remove(start);
        }

        for (Integer item : list) {
            ans += item;
        }

        return ans;
    }

    public static int sumOfLeft2(int[] arr, int jump, int left) {
        int ans = 0;
        ArrayList<Integer> list = (ArrayList<Integer>) Arrays.stream(arr).boxed().collect(Collectors.toList());

        int start = 1;
        while (list.size() > left) {
            start += jump;
            // 为避免越界
            start = start % list.size();
            list.remove(start);
        }

        for (Integer item : list) {
            ans += item;
        }

        return ans;
    }

    /**
     * https://fcqian.blog.csdn.net/article/details/135049122
     * 灰度图存储
     * @param nums
     * @param pos
     * @return
     */
    public static int getRayValue(int[] nums, int[] pos) {
        int rows = nums[0];
        int cols = nums[1];

        int[] graph = new int[rows*cols];
        int start = 0;

        for (int i=2; i<nums.length; i+=2) {
            int gray = nums[i];
            int len = nums[i+1];

            Arrays.fill(graph, start, start+len, gray);
            start += len;
        }

        int target = pos[0] * rows + pos[1];
        return graph[target];
    }

    // 分块，连续相同组的小朋友
    static class Block {
        int groupId;
        int count;

        public Block(int groupId, int count) {
            this.groupId = groupId;
            this.count = count;
        }
    }

    /**
     * 学生重新排队
     * https://fcqian.blog.csdn.net/article/details/134590660
     * @param studentArr
     * @param groupArr
     * @return
     */
    public static int getTiaoZhengTimes(int[] studentArr, int[] groupArr ) {
        // 移动次数
        int ans = 0;
        // 构建一个学生排序和对应分组的映射关系
        int sdtNum = studentArr.length;
        int[] studentGroup = new int[sdtNum+1];

        for (int i=0; i<sdtNum; i++) {
            int num = groupArr[i];
            studentGroup[num] = i/3;
        }

        LinkedList<Block> queue = new LinkedList<>();
        for (int num : studentArr) {
            int groupId = studentGroup[num];

            if (queue.isEmpty() || queue.getLast().groupId != groupId) {
                queue.addLast(new Block(groupId, 1));
            } else {
                queue.getLast().count++;
            }
        }

        while (!queue.isEmpty()) {
            Block first = queue.removeFirst();

            // 当first.count = 1 时，情况如下
            // 1 x 1 1 y z
            // 1 x 1 y 1 z
            if (first.count == 1) {
                Block cur = queue.getFirst();

                // 判断x是否存在连续完整分组
                while (cur.count == 3) {
                    queue.removeFirst();
                    cur = queue.getFirst();
                }

                if (cur.groupId == first.groupId && cur.count == 2) {
                    // 情况如下：1 2 2 2 x[1 1]
                    // 将开头1，移动进x中
                    ans++;
                    queue.removeFirst();
                } else {
                    // 情况如下：
                    // 1 x[2 2] 1 1
                    // 1 x[2] 1 2 1
                    // 将后面的两个1移动到开头
                    ans += 2;
                    queue = confirm(queue, first.groupId);
                }
            } else if (first.count == 2){
                // 当first.count == 2 时，情况如下：
                // 1 1 x 1 y z
                ans += 1;
                queue = confirm(queue, first.groupId);
            }
        }

        return ans;
    }

    public static LinkedList<Block> confirm(LinkedList<Block> queue, int confirmed_groupId) {
        LinkedList<Block> back_queue = new LinkedList<>();

        while (!queue.isEmpty()) {
            Block first = queue.removeFirst();
            if (first.groupId == confirmed_groupId) {
                continue;
            }

            if (back_queue.isEmpty() || back_queue.getLast().groupId != first.groupId) {
                back_queue.addLast(new Block(first.groupId, first.count));
            } else {
                back_queue.getLast().count += first.count;
            }
        }

        return back_queue;
    }

    /**
     * 求字符串中所有整数的最小和
     * https://fcqian.blog.csdn.net/article/details/127418073
     * @param str
     * @return
     */
    public static int getMinSumInStr(String str) {
        Integer ans = 0;

        Pattern p = Pattern.compile("-(\\d+)?");
        // Pattern p = Pattern.complie("-(\\d+)?");
        Matcher m = p.matcher(str);

        List<Integer> numList = new ArrayList<>();
        while (m.find()) {
            numList.add(Integer.valueOf(m.group()));
        }

        str = str.replaceAll(p.pattern(), "x");
        System.out.println(str);

        int len = str.length();
        for (int i=0; i<len; i++) {
            char c = str.charAt(i);
            if (c >= '0' && c <= '9') {
                numList.add(Integer.valueOf(c+""));
            }
        }

        for (Integer num : numList) {
            System.out.println(num + " ");
            ans += num;
        }
        return ans;
    }

    /**
     * 考勤信息
     * https://fcqian.blog.csdn.net/article/details/127944519
     * @return
     */
    public static boolean canGetQuanQinJiang(String[] record) {
        // 总缺勤次数
        int absent = 0;
        // 滑动窗口内正常上班的次数
        int present = 0;
        // 记录前一次的考勤记录
        String preRecord = "";

        for (int i=0; i<record.length; i++) {
            if (i>=7) {
                if ("present".equals(record[i-7])) {
                    present--;
                }
            }

            String curRecord = record[i];

            switch (curRecord) {
                case "absent":
                    if (++absent > 1) return false;
                    break;
                case "late":
                case "leavearly":
                    if ("late".equals(preRecord) ||"leavearly".equals(preRecord)) {
                        return false;
                    }
                    break;
                case "present":
                    present++;
                    break;
            }

            preRecord = curRecord;

            int window_len = Math.min(i+1, 7);
            if (window_len - present > 3) {
                return false;
            }
        }

        return true;
    }

    public static boolean isGetQuanQinJiang(String[] record) {
        // 总缺勤次数
        int absent = 0;
        // 滑动窗口内正常上班的次数
        int present = 0;
        // 记录前一次的考勤记录
        String preRecord = "";

        int len = record.length;
        for (int i=0; i<len; i++) {
            if (i >= 7) {
                if ("present".equals(record[i-7])) {
                    present--;
                }
            }

            String curRecord = record[i];
            switch (curRecord) {
                case "absent":
                    if (++absent > 1) return false;
                    break;
                case "late":
                case "leavearly":
                    if ("late".equals(preRecord) ||"leavearly".equals(preRecord)) {
                        return false;
                    }
                    break;
                case "present":
                    present++;
                    break;
            }

            preRecord = curRecord;
            int window_len = Math.min(i+1, 7);
            if (window_len - present > 3) {
                return false;
            }
        }

        return true;
    }

    /**
     * 执行时长
     * https://fcqian.blog.csdn.net/article/details/127417767
     * @param maxCount
     * @param tasks
     * @return
     */
    public static int getCostMinGPUSeconds(int maxCount, int[] tasks) {
        int time = 0;
        int remain = 0;

        for (int task : tasks) {
            if (task + remain > maxCount) {
                remain = task + remain - maxCount;
            } else {
                remain = 0;
            }
            time++;
        }

        while (remain > 0) {
            remain -= maxCount;
            time++;
        }

        return time;
    }

    /**
     * 查找众数及中位数
     * https://fcqian.blog.csdn.net/article/details/127332842
     * @param nums
     * @return
     */
    public static int getMiddleNum(int[] nums) {
        HashMap<Integer, Integer> countMap = new HashMap<>();

        for (int num : nums) {
            countMap.put(num, countMap.getOrDefault(num, 0) + 1);
        }

        int max = countMap.values().stream().max((a,b) -> a - b).orElse(0);
        // 挑选出众数来
        ArrayList<Integer> ans = new ArrayList<>();
        for (Integer k : countMap.keySet()) {
            if (countMap.get(k) == max) {
                ans.add(k);
            }
        }

        ans.sort((a, b) -> a - b);

        // 中位数取值
        int mid = ans.size() / 2;
        if (ans.size() % 2 == 0) {
            return (ans.get(mid) + ans.get(mid - 1)) / 2;
        } else {
            return ans.get(mid);
        }
    }

    /**
     * 最大N个数与最小N个数的和
     * https://fcqian.blog.csdn.net/article/details/127417952
     * @param arr
     * @param n
     * @return
     */
    public static int getSumOfNNums(int[] arr, int n) {
        if (n <= 0) {
            return -1;
        }

        HashSet<Integer> set = new HashSet<>();
        for (int val : set) {
            if (val <0 || val > 1000) {
                return -1;
            }
            set.add(val);
        }

        if (set.size() < n * 2) {
            return -1;
        }

        Integer[] distinctArr = set.toArray(new Integer[0]);
        Arrays.sort(distinctArr, (a, b) -> a - b);
        int l = 0;
        int r = distinctArr.length - 1;
        int ans = 0;

        while (n > 0) {
            ans += distinctArr[l] + distinctArr[r];
            l++;
            r--;
            n--;
        }

        return ans;
    }

    /**
     * 整数对最小和
     * https://fcqian.blog.csdn.net/article/details/127969628
     * @param arr1
     * @param arr2
     * @param k
     * @return
     */
    public static int getMinSumOfPairs(int[] arr1, int[] arr2, int k) {
        int sum = 0;
        ArrayList<Integer> pairs = new ArrayList<>();

        for (int v1 : arr1) {
            for (int v2 : arr2) {
                pairs.add(v1 + v2);
            }
        }

        pairs.sort((a, b) -> a - b);

        for(int i = 0; i < k; i++) {
            sum += pairs.get(i);
        }

        return sum;
    }

    public static long calculateGraphArea(Scanner scanner) {
        int n = scanner.nextInt();
        int end_x = scanner.nextInt();

        long ans = 0;
        int last_x = 0;
        int last_y = 0;

        for (int i=0; i<n; i++) {
            int cur_x = scanner.nextInt();
            int offset_y = scanner.nextInt();

            ans += (cur_x - last_x) * Math.abs(offset_y);

            last_x = cur_x;
            last_y = offset_y;
        }

        if (end_x > last_x) {
            ans += (end_x - last_x) * Math.abs(last_y);
        }

        System.out.println(ans);
        return ans;
    }

    /**
     * 攀登者1
     * https://fcqian.blog.csdn.net/article/details/134864087
     * 查找山峰的数量
     * @param arr
     * @return
     */
    public static int getPeekNum(int[] arr) {
        int ans = 0;
        int len = arr.length;
        if (len <= 0) {
            return ans;
        }

        for (int i=0; i<len; i++) {
            int curHeight = arr[i];
            int leftHeight = i-1>=0 ? arr[i-1] : 0;
            int rightHeight = i+1 < len ? arr[i+1] : 0;
            if (curHeight > leftHeight && curHeight > rightHeight) {
                ans++;
            }
        }

        return ans;
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//        int[] arr = Arrays.stream(scanner.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
//        int jump = scanner.nextInt();
//        int left = scanner.nextInt();
//
//        int ans = sumOfLeft(arr, jump, left);
//        System.out.println(ans);

//        int[] nums = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
//        int[] pos = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
//        int grayValue = getRayValue(nums, pos);
//        System.out.println(grayValue);

//        int[] studentArr = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
//        int[] groupArr = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
//        int tiaoZhengTimes = getTiaoZhengTimes(studentArr, groupArr);
//        System.out.println(tiaoZhengTimes);

//        String str = scanner.nextLine();
//        int minSum = getMinSumInStr(str);
//        System.out.println(minSum);

        int n = Integer.parseInt(scanner.nextLine());
        String[][] records = new String[n][];
        for (int i=0;i<n; i++) {
            records[i] = scanner.nextLine().split(" ");
        }
        StringJoiner sj = new StringJoiner(" ");
        for (int i=0; i<n; i++) {
            sj.add(canGetQuanQinJiang(records[i]) + "");
        }
        System.out.println(sj);

//        int n1 = scanner.nextInt();
//        int[] arr1 = new int[n1];
//        for (int i=0; i<n1; i++) {
//            arr1[i] = scanner.nextInt();
//        }
//
//        int n2 = scanner.nextInt();
//        int[] arr2 = new int[n2];
//        for (int i=0; i<n2; i++) {
//            arr2[i] = scanner.nextInt();
//        }
//
//        int k = scanner.nextInt();
//        System.out.println(getMinSumOfPairs(arr1, arr2, k));

//        int[] peeks = {0, 1, 4, 3, 1, 0, 0, 1, 2, 3, 1, 2, 1, 0};
//        int ans = getPeekNum(peeks);
//        System.out.println(ans);
    }

}
